package com.Prot2.Logger;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;

import com.Prot2.Globals;
import com.Prot2.R;

import weka.classifiers.Classifier;
import weka.core.DenseInstance;
import weka.core.Instance;
import weka.core.Instances;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

public class RecognitionWorker {
	
	public static final String TAG="RecognitionWorker";
	private Context c;
	private Instances format;
	private Instance mInstance;
	
	
	Classifier mClassifier = null;
	
	public RecognitionWorker(Context context){
		BufferedReader br;
		BufferedInputStream bis;
		ObjectInputStream ois;

		c=context;
		
		
		//deserialize the model and obtain arff format
		
		bis = new BufferedInputStream(c.getResources().openRawResource(R.raw.model_j48_phone3));
		br = new BufferedReader(new InputStreamReader(c.getResources().openRawResource(R.raw.arff_dummy)));
		
		try{
			ois = new ObjectInputStream(bis);			
			
			mClassifier = (weka.classifiers.Classifier) ois.readObject();
			ois.close();
	
			
			format=new Instances(br);
			br.close();
			if (format.classIndex() == -1) 
				format.setClassIndex(format.numAttributes() - 1); //In case no target attribute was set, use last one
			
			mInstance = new DenseInstance(11);
			mInstance.setDataset(format);
			
		}catch(Exception e){e.printStackTrace();}
	}
	
	
	
	private static double getMean(double[] dataStream, int winSize){
		double sum=0;
		double size = (double)winSize;
		for (double a : dataStream){
			sum += a;
		}
		return sum/size;
	}
	
	private static double getVar(double[] dataStream, int winSize){
		double mean=getMean(dataStream, winSize);
		double size = (double)winSize;
		double temp=0;
		for(double a : dataStream){
			temp+=(mean-a)*(mean-a);
		}
		return temp/size;
		}	
	
	
	public void evaluateDataTable(double[][] data, int samplingTime, int samplingRate){
		//data in format [sensor data][samples in time] which is [7][samplingTime/samplingRate]
		int winSize = samplingTime/samplingRate;
		double[] dataStream = new double[winSize];
		double x=0,y=0,z=0;
		
		for(int i=0; i<winSize; i++){
			x=data[0][i];
			y=data[1][i];
			z=data[2][i];
			dataStream[i]=Math.sqrt(x*x+y*y+z*z);
		}
		
		double meanAcc=getMean(dataStream,winSize);
		double meanLight=getMean(data[3],winSize);
		double meanHum=getMean(data[4],winSize);
		double meanTemp=getMean(data[5],winSize);
		double meanPress=getMean(data[6],winSize);
		
		
		double varAcc=getVar(dataStream,winSize);
		double varLight=getVar(data[3],winSize);
		double varHum=getVar(data[4],winSize);
		double varTemp=getVar(data[5],winSize);
		double varPress=getVar(data[6],winSize);
		
		double features[] = new double[] {meanAcc,varAcc,meanLight,varLight,meanHum,varHum,meanTemp,varTemp,meanPress,varPress}; 
		
		try{
			// set attributes
			for(int i = 0; i < features.length; i++){
				System.out.println("feature "+String.valueOf(i)+"  : "+ String.valueOf(features[i]));
				mInstance.setValue(format.attribute(i),features[i]);
			}
			// set class which is to be classified
			mInstance.setMissing(format.attribute(10));
			//classify the instance and make it available
			Globals.previouslyDetectedLabel = Globals.currentlyDetectedLabel;
			int labelPos  = (int)mClassifier.classifyInstance(mInstance);
			System.out.println("classifier found index"+labelPos);
			Globals.currentlyDetectedLabel = Integer.valueOf(mInstance.classAttribute().value(labelPos));
			System.out.println("classifier found value"+Globals.currentlyDetectedLabel);
			Log.w(TAG,"Currently detected label: "+Globals.currentlyDetectedLabel);
			
			
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	
	}
	
	

	

	
}
